import Vue                                                                             from 'vue';
import Bridge                                                                          from '@/utily/bridge'
import moment                                                                          from 'moment'
import axios                                                                           from 'axios'
import Swal                                                                            from 'sweetalert2'
import { readerImage }                                                                 from '@/utily/util'
import { addImageProcess, getChannel, getOptionForType, oneOf, sleep, validationType } from "../utily/util";

const oneMin = 1000 * 60;

let firstMessage = true;

export default {
    namespaced: true,
    state     : {
        bridgeObject: {},
        message     : {},
        prevTime    : null,
        monitor     : {},
        submiting   : false,
        submited    : false,
    },
    mutations : {
        submiting(state, data) {
            state.submiting = data;
        },
        submited(state, data) {
            state.submited = data;
        },
        bridgeObject(state, { bridge, type }) {
            Vue.set(state.bridgeObject, type, bridge);
        },
        message(state, { message, type }) {
            Vue.set(state.message, type, message);
        },
        messageAdd(state, { item, type }) {
            if (!state.message[ type ]) {
                Vue.set(state.message, type, []);
            }
            state.message[ type ].push(item);
        },
        prevTime(state, item) {
            state.prevTime = item;
        },
        addMonitor(state, {
            key,
            value
        }) {
            state.monitor[ key ] = value;
        },
        removeMonitor(state, key) {
            delete state.monitor[ key ];
        },
        clearMonitor(state) {
            state.monitor = {}
        }
    },
    actions   : {
        bridge({ commit, state, dispatch }, {
            value,
            typeName
        }) {
            let bridge = state.bridgeObject[ typeName ];

            if (bridge === undefined) {
                let option = getOptionForType(typeName);
                bridge     = new Bridge({
                    typeName: typeName,
                    tag     : CONFIG.BASE.PAGE_TAG,
                    make    : true,
                    text    : encodeURIComponent(value),
                    messageCallback(message) {
                        switch (option.type) {
                            case "kst":
                                dispatch('filterMessage', { message, typeName: typeName });
                                break;
                            case "swt" :
                                dispatch('swtFilterMessage', { message, type: 'back', typeName: typeName });
                                break;
                        }
                    }
                });
                commit('bridgeObject', {
                    bridge,
                    type: typeName
                });
            }
            return bridge;
        },
        /**
         * (已废弃)  发送图片到快商通.
         * @param dispatch
         * @param commit
         * @param files
         * @param callback
         * @returns {Promise<void>}
         */
        async sendImage({ dispatch, commit }, { files, callback }) {
            const bridge = await dispatch('bridge');

            bridge.postMessageToChild({
                sendImage: files
            });

            readerImage(files[ 0 ], (reader) => {
                const img = new Image();

                img.addEventListener('load', () => {
                    if (typeof callback === 'function') {
                        callback(reader);
                    }

                    dispatch('createTime');
                    commit('messageAdd', {
                        value    : `<img referrerpolicy="no-referrer" class="mw-img-i" src="${ reader.result }" />`,
                        type     : 'right',
                        animation: 'right-default'
                    })
                });
                img.src = reader.result;
            })
        },
        async sendText({ commit, dispatch, state }, {
            value,
            display = true,
            send = true,
            aglPlus = false,
            typeName = CONFIG.BASE.TYPE
        }) {
            if (!validationType(typeName)) {
                throw new TypeError('Type Is Not Exists.');
            }

            console.log('aglPlus :', aglPlus, $_aglPush);
            aglPlus && $_aglPush();
            if (send) {
                console.log('typeName :', typeName);

                if (window.__chatType === 'yiliao') {
                    console.log('sendMessage :', value);
                    webcall.sendMessage(value);
                } else {
                    let hasBridge = state.bridgeObject[ typeName ];
                    const bridge  = await dispatch('bridge', {
                        value,
                        typeName
                    });

                    hasBridge && bridge.postMessageToChild({
                        sendMessage: value
                    });
                }
            }

            if (display && window.__chatType !== 'yiliao') {
                dispatch('filterMessage', {
                    message: {
                        value    : value,
                        type     : 'right',
                        animation: 'right-default'
                    },
                    pass   : true
                })
            }
            dispatch('runMonitor', value);
        },
        async sendInputText({ state }, {
            value,
            typeName = CONFIG.BASE.TYPE
        }) {
            let bridge = state.bridgeObject[ typeName ];

            bridge && bridge.postMessageToChild({
                inputDataChange: value,
            });

        },
        runMonitor({ getters }, value) {
            let monitor = getters.monitor;
            let keys    = Object.keys(monitor);

            if (keys.length > 0) {
                keys.forEach((i) => {
                    let item = monitor[ i ];
                    if (typeof item === 'function') {
                        item(value);
                    }
                })
            }
        },
        swtFilterMessage({ dispatch }, { message, pass = false, type = 'default', typeName }) {
            message = [].concat(message);

            if (type === 'back') {
                if (firstMessage && message.length > 1) {
                    firstMessage = false;
                    return;
                }

                message = message.filter(e => !oneOf([ 'right', 'center' ], e.type));
            }

            dispatch('filterMessage', {
                message,
                pass,
                typeName
            })
        },
        async filterMessage({ commit, dispatch }, {
            message,
            typeName = CONFIG.BASE.TYPE,
            pass = false,
            duration = 0,
        }) {
            console.log('message :', message);
            let arr = [ 'advertising', 'broadcast', 'advertisings', 'left' ];
            if (window.__chatType === 'yiliao') arr.push('right');

            message = [].concat(message).filter((item) => {
                return item && (pass || (arr.includes(item.type) && item.value !== 'NOT_FOUNT_MSG'));
            });
            for (let [ index, item ] of message.entries()) {
                let dur = parseInt(item.duration) || 0;
                if (index !== 0) dur += 400;

                console.log('dur :', dur);

                if (dur) {
                    await sleep(dur);
                }
                ![ 'advertising', 'broadcast', 'advertisings' ].includes(item.type) && dispatch('createTime');
                commit('messageAdd', { item, type: typeName });
            }

        },
        createTime({ getters, commit }) {
            const now = moment();
            if (getters.prevTime) {
                if (now.diff(getters.prevTime) < oneMin) {
                    return;
                }
            }

            commit('prevTime', now);
            commit('messageAdd', {
                type : 'time',
                value: now,
            })
        },
        async checkIsSubmitted({ getters }) {
            let test = getters.submited ? await Swal.fire({
                title             : '提示',
                text              : "你已提交检查数据,是否重新提交?",
                icon              : 'warning',
                showCancelButton  : true,
                confirmButtonColor: '#3085d6',
                cancelButtonColor : '#d33',
                confirmButtonText : '确定提交',
                cancelButtonText  : '点错了',
            }) : { value: true };

            return test && test.value;
        },
        async postToServe({ commit }, data) {
            console.log('data :', data);

            data.channel = getChannel();
            data.url     = window.location.href;

            commit('submiting', true);
            let url = CONFIG.TYPE_OPTION.post_url;
            try {
                let response = await axios.post(url, data);

                console.log(Swal);
                if (response.status === 200) {
                    commit('submited', true);

                    Swal.fire(
                        '提交成功!',
                        '我们会尽快联系您.请留意!',
                        'success'
                    );
                } else {
                    Swal.fire(
                        '提交失败!',
                        '目前检测人员过多,请拨打电话!<br/><a href="tel:029-88828888">029-88828888</a>',
                        'warning',
                    );
                }

            } catch (e) {
                Swal.fire(
                    '提交失败!',
                    '目前检测人员过多,请拨打电话!<br/><a href="tel:029-88828888">029-88828888</a>',
                    'warning',
                );
            }
            commit('submiting', false);


        },
    },
    getters   : {
        bridge(state) {
            return state.bridge;
        },
        prevTime(state) {
            return state.prevTime;
        },
        defaultMessage(state) {
            if (!state.message[ CONFIG.BASE.TYPE ]) {
                Vue.set(state.message, CONFIG.BASE.TYPE, []);
            }
            return state.message[ CONFIG.BASE.TYPE ];
        },
        monitor(state) {
            return state.monitor;
        },
        submiting(state) {
            return state.submiting;
        },
        submited(state) {
            return state.submited;
        },
    }
}
